#!/usr/bin/env python

import os
import sys
import pygame
import random
try: import nidaqmx
except: pass
import components
import multiprocessing
import pygame.locals

from ..._app import App
from _config import Config

class App(App):
    '''App class

    @author Julot <andy.julot@gmail.com>
    @since Sunday, January 15, 2012. 05:05 PM'''
    
    WIDTH = 1280
    CHANNEL_WIDTH = 53
    HEIGHT = 700
    STEP = 5
    Y_0 = 30
    # max = WIDTH / STEP
    MAX = 700 / 5
    
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    BLUE = (0, 0, 255)
    GREEN = (0, 255, 0)
    CYAN = (0, 255, 255)
    RED = (255, 0, 0)
    MAGENTA = (255, 0, 255)
    YELLOW = (255, 255, 0)
    
    def _readDevice(self, connection):
        config = Config()
        try: device = config.get('Device', 'Name')
        except: device = 'Dev1'
        gains = {}
        for index in range(24):
            gains[index] = int(config.getint('Gain', '%s' % (index + 1)))
        frequency = '16 ms'
        rate = components.Nidaqmx.calcRate(frequency)
        del config
        
        task = nidaqmx.AnalogInputTask()
        maxs = []
        for channel in range(24):
            max = 11 - gains[channel]
            maxs.append(max)
            task.create_voltage_channel('%s/ai%s' % (device, channel),
                                        terminal='rse', min_val=-max,
                                        max_val=max, units='volts')
        task.configure_timing_sample_clock(rate=rate, samples_per_channel=1)
        task.start()
        
        while True:
            datum = task.read(1, fill_mode='group_by_scan_number')[0]
##            print datum
            data = []
            for index in range(24):
##                value = datum[index]
                # Value to stored in SegY file
                value = int(((datum[index] * 32768) / maxs[index]) + 32768)
                # Value to view in display
                value = (value * self.CHANNEL_WIDTH) / 65536
                data.append(value)
##            print data
            connection.send(('data', data))
            
            if connection.poll():
                message = connection.recv()
                if message == 'quit': break
        
        task.stop()
    
    def run(self):
        imported = True
        try: import nidaqmx
        except: imported = False
    
        homeDir = os.path.realpath(os.path.dirname(sys.argv[0]))
        load = pygame.image.load
        
        pygame.init()
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        path = os.path.join('resources', 'images', 'monitor', 'icon.png')
        path = '%s%s%s' % (homeDir, os.path.sep, path)
        icon = load(path)
        pygame.display.set_icon(icon)
        screen = pygame.display.set_mode((self.WIDTH, self.HEIGHT), 0, 32)
        
        fonts = {'channels': {'font': None}}
        path = os.path.join('resources', 'fonts', 'Impress BT.ttf')
        path = '%s%s%s' % (homeDir, os.path.sep, path)
        font = pygame.font.Font(path, 12)
        fonts['channels']['font'] = font
        
        for i in range(24):
            text = font.render('%s' % (i + 1), True, self.BLACK)
            width = text.get_width()
            x = ((self.CHANNEL_WIDTH - width) / 2) + (i * self.CHANNEL_WIDTH)
            fonts['channels'][i] = (text, (x, 5))
        
        data = []
        line = pygame.draw.aaline
        
        parentConn, childConn = multiprocessing.Pipe()
        process = multiprocessing.Process(target=self._readDevice,
                                          args=(childConn,))
        if imported: process.start()
        else: clock = pygame.time.Clock()
        
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.locals.QUIT:
                    parentConn.send('quit')
                    running = False
            
            screen.fill(self.WHITE)
            
            for channel in range(24):
                text, pos = fonts['channels'][channel]
                screen.blit(text, pos)
            
            screen.lock()
            
            line(screen, self.BLACK, (0, 25), (self.WIDTH, 25))
            
            y = 25
            virgin = True
            for datum in data:
                if not virgin:
                    y += self.STEP
                    for channel in range(24):
                        addition = self.CHANNEL_WIDTH * channel
                        x = previousDatum[channel] + addition
                        previous = (x, y - self.STEP)
                        x = datum[channel] + addition
                        current = (x, y)
                        line(screen, self.BLUE, previous, current)
                
                previousDatum = datum
                virgin = False
            
            screen.unlock()
            pygame.display.update()
            
            if not imported: clock.tick(30)
            
            if parentConn.poll():
                key, value = parentConn.recv()
                if key == 'data':
##                    print value[0]
                    data.insert(0, value)
                    try: del data[self.MAX]
                    except: pass
        
        if imported: process.join()
                